/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tallerfinal.util.distributions;

import tallerfinal.util.distributions.factory.GeneratorsFactory;
import tallerfinal.util.enums.DistributionsName;

/**
 *
 * @author ricardo
 */
public class GammaGenerator extends Generator<Double> {
static {
        GeneratorsFactory.getInstance().registerProduct(DistributionsName.GAMMA, GammaGenerator.class);
    }
    private double alfa;
    private double beta;

    public GammaGenerator(double alfa, double beta) {
        this.alfa = alfa;
        this.beta = beta;
    }

    @Override
    public Double generate() {
        double a = 1d / Math.sqrt(2 * alfa - 1);
        double b = alfa - Math.log(4);
        double q = alfa + 1d / a;
        double theta = 4.5;
        double d = 1 + Math.log(theta);
        double u1 = generator.nextDouble();
        double u2 = generator.nextDouble();
        double v = a * Math.log(u1 / (1 - u1));
        double y = alfa * Math.exp(v);
        double z = u1 * u1 * u2;
        double w = b + q * v - y;
        while (w + d - theta * z < 0) {
            if (w >= Math.log(z)) {
                return y * beta;
            } else {
                u1 = generator.nextDouble();
                u2 = generator.nextDouble();
                v = a * Math.log(u1 / (1 - u1));
                y = alfa * Math.exp(v);
                z = u1 * u1 * u2;
                w = b + q * v - y;
            }
        }
        return y * beta;
    }
}
